package multithread;

//单例模式 懒汉模式
//class SingletonLazy {
//    private static SingletonLazy instance = null;//先定义出唯一的实例 置为null
//    public static SingletonLazy getInstance() {
//        //首次调用getInstance时 才创建出实例
//        //后续继续调用 则直接返回 不会继续创建实例 保证唯一
//        if(instance == null){
//            instance = new SingletonLazy();
//        }
//        return instance;
//    }
//
//    private SingletonLazy() {
//        //构造函数设置为私有
//    }
//}

//优化
//class SingletonLazy {
//    private static SingletonLazy instance = null;//先定义出唯一的实例 置为null
//    private static Object locker = new Object();//锁对象
//    public static SingletonLazy getInstance() {
//        synchronized (locker) { //锁对象也可以是类对象 SingletonLazy.class
//            //首次调用getInstance时 才创建出实例
//            //后续继续调用 则直接返回 不会继续创建实例 保证唯一
//            if(instance == null){
//                instance = new SingletonLazy();
//            }
//        }
//        return instance;
//    }
//    private SingletonLazy() {
//        //构造函数设置为私有
//    }
//}

//再次优化
//class SingletonLazy {
//    private static SingletonLazy instance = null;//先定义出唯一的实例 置为null
//    private static Object locker = new Object();//锁对象
//    public static SingletonLazy getInstance() {
//        if(instance == null ){
//            //instance为空——>首次调用 ——> 需要考虑线程安全问题 需要加锁
//            //不为空 ， 不是第一次调用，不需要加锁
//            synchronized (locker) {
//                if(instance == null){
//                    instance = new SingletonLazy();
//                }
//            }
//        }
//        return instance;
//    }
//    private SingletonLazy() {
//        //构造函数设置为私有
//    }
//}

//再再再！！！再次优化
class SingletonLazy {
    //先定义出唯一的实例 置为null
    //用volatile修饰，避免指令重排序
    private volatile static SingletonLazy instance = null;
    private static Object locker = new Object();//锁对象
    public static SingletonLazy getInstance() {
        if(instance == null ){
            //instance为空——>首次调用 ——> 需要考虑线程安全问题 需要加锁
            //不为空 ， 不是第一次调用，不需要加锁
            synchronized (locker) {
                if(instance == null){
                    instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }
    private SingletonLazy() {
        //构造函数设置为私有
    }
}

public class ThreadDemo9 {
    public static void main(String[] args) {
        SingletonLazy s1=SingletonLazy.getInstance();
        SingletonLazy s2=SingletonLazy.getInstance();

        System.out.println(s1==s2);
    }
}
